package com.xysoft.admin.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.xysoft.admin.common.PageModel;
import com.xysoft.admin.common.SessionInfo;
import com.xysoft.admin.dto.ActionTreeDTO;
import com.xysoft.admin.dto.OrganizationDTO;
import com.xysoft.admin.dto.RoleDTO;
import com.xysoft.admin.service.IManageRoleService;
import com.xysoft.model.Action;
import com.xysoft.model.ActionColumn;
import com.xysoft.model.Organization;
import com.xysoft.model.Role;
import com.xysoft.model.RoleAction;
import com.xysoft.model.User;
import com.xysoft.model.UserRole;
import com.xysoft.util.JsonUtil;
import com.xysoft.util.RequestUtil;

@Component
@SuppressWarnings("unchecked")
public class ManageRoleServiceImpl extends BaseServiceImpl implements IManageRoleService {
	
	@Transactional(readOnly = true)
	public String get(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		int page = Integer.valueOf(RequestUtil.getValue(request, "page"));
		int limit = Integer.valueOf(RequestUtil.getValue(request, "limit"));
		Organization organ = (Organization)this.getBaseDao().get(Organization.class, sessionInfo.getOrgId());
		String hql = "from Role r where r.deleted = 0 and r.front = 0 and r.organization.id = ?";
		List<Object> values = new ArrayList<Object>();
		values.add(sessionInfo.getOrgId());
		String name = RequestUtil.getValue(request, "name").trim();
		if(!"".equals(name)) {
			hql = hql + " and r.name like ?";
			values.add("%" + name + "%");
		}
		hql = hql + " order by r.id desc";
		List<Role> roles = this.getBaseDao().find(hql, page, limit, values);
		List<RoleDTO> dtos = new ArrayList<RoleDTO>();
		for (Role role : roles) {
			RoleDTO dto = new RoleDTO();
			BeanUtils.copyProperties(role, dto);
			dto.setOrgan(organ.getName());
			dtos.add(dto);
		}
		long count = this.getBaseDao().count("select count(*) " + hql, values);
		PageModel pm = new PageModel();
		pm.setTotal(count);
		pm.setDatas(dtos);
		return JsonUtil.toStringFromObject(pm);
	}
	
	@Transactional(readOnly = true)
	public String getOrgan(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		User user = (User)this.getBaseDao().get(User.class, sessionInfo.getUser().getId());
		Organization organ = user.getOrganization();
		String node = request.getParameter("node");
		//查询SQL语句
		String hql = "from Organization o where o.deleted = 0";
		//查询SQL值
		List<Object> values = new ArrayList<Object>();
		if (node == null || "root".equals(node)) {
			hql = hql + " and o.id = ?";
			values.add(organ.getId());
		} else {
			hql = hql + " and o.keyChar like ? and o.parent.id = ?";
			values.add(organ.getKeyChar() + "%");
			values.add(Integer.valueOf(node));
		}
		List<Organization> organizations = this.getBaseDao().find(hql, values);
		List<OrganizationDTO> dtos = new ArrayList<OrganizationDTO>();
		for (Organization oo : organizations) {
			OrganizationDTO dto = new OrganizationDTO();
			BeanUtils.copyProperties(oo, dto);
			if (oo.getNumber() > 0) {
				dto.setExpandable(true);
				dto.setLeaf(false);
			} else {
				dto.setExpandable(false);
				dto.setLeaf(true);
			}
			dtos.add(dto);
		}
		return JsonUtil.toString(dtos);
	}

	@Transactional
	public Map<String,Object> addOrModify(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		String idStr = RequestUtil.getValue(request, "id");
		Role role = null;
		if ("".equals(idStr)) {
			role = new Role();
			role.setFront(false);
			role.setDeleted(false);
			Organization organ = (Organization)this.getBaseDao().get(Organization.class, sessionInfo.getOrgId());
			role.setOrganization(organ);
		} else {
			role = (Role)this.getBaseDao().get(Role.class, Integer.valueOf(idStr));
			if (!role.getOrganization().getKeyChar().equals(sessionInfo.getKeyChar())) return null;
		}
		role.setName(RequestUtil.getValue(request, "name"));
		role.setRemark(RequestUtil.getValue(request, "remark"));
		this.getBaseDao().save(role);
		Map<String,Object> modelMap = new HashMap<String,Object>(3);
		modelMap.put("success", true);
		modelMap.put("title", "保存成功！");
		modelMap.put("msg", "");
		return modelMap;
	}

	@Transactional
	public Map<String, Object> remove(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		int id = Integer.valueOf(RequestUtil.getValue(request, "id"));
		Role role = (Role)this.getBaseDao().get(Role.class, id);
		if (!role.getOrganization().getKeyChar().equals(sessionInfo.getKeyChar()) 
				|| role.isDeleted()) return null;
		List<UserRole> ras = this.getBaseDao().find("from UserRole ur where ur.role.id = ?", id);
		Map<String,Object> modelMap = new HashMap<String,Object>(3);
		modelMap.put("success", true);
		for (UserRole ra : ras) {
			this.getBaseDao().delete(ra);
		}
		this.getBaseDao().delete(role);
		modelMap.put("ok", true);
		modelMap.put("msg", "删除成功！");
		return modelMap;
	}

	@Transactional
	public String getAction(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		List<String> actions = sessionInfo.getActions();
		List<Action> acts = this.getBaseDao().find("from Action where front = 0 and level >= ?", 
				sessionInfo.getTypeValue().length());
		Map<String, Action> actMaps = new HashMap<String, Action>();
		Map<Integer, Integer> aidMaps = new HashMap<Integer, Integer>();
		for (Action act : acts) {
			actMaps.put(act.getCode(), act);
			if (act.getCode().indexOf("?index") != -1) {
				aidMaps.put(act.getColumn().getId(), act.getId());
			}
		}
		List<ActionColumn> acs = this.getBaseDao().find("from ActionColumn order by level desc");
		Map<Integer, ActionColumn> colMaps = new HashMap<Integer, ActionColumn>();
		Map<Integer, ActionTreeDTO> trees = new HashMap<Integer, ActionTreeDTO>();
		for (ActionColumn ac : acs) {
			colMaps.put(ac.getId(), ac);
		}
		Map<Integer, ActionTreeDTO> dtos = new HashMap<Integer, ActionTreeDTO>();
		for (String action : actions) {
			if (!actMaps.containsKey(action)) continue;
			Action aid = actMaps.get(action);
			int id = aid.getColumn().getId();
			ActionColumn ac = colMaps.get(id);
			if (dtos.containsKey(id)) {
				if (aid.isLeaf()) continue;
				ActionTreeDTO dto = dtos.get(id);
				List<ActionTreeDTO> lst = dto.getChildren();
				ActionTreeDTO dtoOne = new ActionTreeDTO();
				dtoOne.setId(aid.getId());
				dtoOne.setText(aid.getKeyName());
				dtoOne.setChecked(false);
				dtoOne.setExpanded(false);
				dtoOne.setIcon("../manage/pic/menu/11.png");
				dtoOne.setLeaf(true);
				lst.add(dtoOne);
				dto.setChildren(lst);
				dtos.put(id, dto);
			} else {
				if (aid.isLeaf()) {
					ActionTreeDTO dto = new ActionTreeDTO();
					dto.setId(aid.getId());
					dto.setChecked(false);
					dto.setExpanded(false);
					dto.setIcon("../manage/pic/menu/" + ac.getIcon());
					dto.setLeaf(false);
					dto.setText(ac.getName());
					dtos.put(id, dto);
				} else {
					int pact = aidMaps.get(id);
					ActionTreeDTO dto = new ActionTreeDTO();
					dto.setId(pact);
					dto.setChecked(false);
					dto.setExpanded(false);
					dto.setIcon("../manage/pic/menu/" + ac.getIcon());
					dto.setLeaf(false);
					dto.setText(ac.getName());
					List<ActionTreeDTO> lst = dto.getChildren();
					//操作节点
					ActionTreeDTO dtoOne = new ActionTreeDTO();
					dtoOne.setId(aid.getId());
					dtoOne.setText(aid.getKeyName());
					dtoOne.setChecked(false);
					dtoOne.setExpanded(false);
					dtoOne.setIcon("../manage/pic/menu/11.png");
					dtoOne.setLeaf(true);
					lst.add(dtoOne);
					dto.setChildren(lst);
					dtos.put(id, dto);
				}
			}
		}
		for (ActionColumn ac : acs) {
			ActionTreeDTO dto = null;
			if (ac.getLevel() == 3) {
				if (!dtos.containsKey(ac.getId())) continue;
				dto = dtos.get(ac.getId());
				trees.put(ac.getId(), dto);
				int pid = 0 - ac.getParent().getId();
				ActionColumn pac = colMaps.get(0 - pid);
				ActionTreeDTO pdto = null;
				if (trees.containsKey(pid)) {
					pdto = trees.get(pid);
					List<ActionTreeDTO> lst = pdto.getChildren();
					lst.add(dto);
					pdto.setChildren(lst);
					trees.put(pid, pdto);
				} else {
					pdto = new ActionTreeDTO();
					pdto.setId(pid);
					pdto.setChecked(false);
					pdto.setExpanded(true);
					pdto.setLeaf(false);
					pdto.setIcon("../manage/pic/menu/" + pac.getIcon());
					pdto.setText(pac.getName());
					List<ActionTreeDTO> lst = pdto.getChildren();
					lst.add(dto);
					pdto.setChildren(lst);
					trees.put(pid, pdto);
				}
			} else if (ac.getLevel() == 2) {
				if (!trees.containsKey(0 - ac.getId())) continue;
				dto = trees.get(0 - ac.getId());
				int pid = 0 - ac.getParent().getId();
				ActionColumn pac = colMaps.get(0 - pid);
				ActionTreeDTO pdto = null;
				if (trees.containsKey(pid)) {
					pdto = trees.get(pid);
					List<ActionTreeDTO> lst = pdto.getChildren();
					lst.add(dto);
					pdto.setChildren(lst);
					trees.put(pid, pdto);
				} else {
					pdto = new ActionTreeDTO();
					pdto.setId(pid);
					pdto.setChecked(false);
					pdto.setExpanded(true);
					pdto.setLeaf(false);
					pdto.setParent(9999);
					pdto.setIcon("../manage/pic/menu/" + pac.getIcon());
					pdto.setText(pac.getName());
					List<ActionTreeDTO> lst = pdto.getChildren();
					lst.add(dto);
					pdto.setChildren(lst);
					trees.put(pid, pdto);
				}
			}
		}
		//返回数据集
		List<ActionTreeDTO> autos = new ArrayList<ActionTreeDTO>();
		for (ActionTreeDTO atd : trees.values()) {
			if (atd.getParent() == 9999) {
				autos.add(atd);
			}
		}
		return JsonUtil.toString(autos);
	}

	@Transactional
	public Map<String, Object> getAuto(HttpServletRequest request,
			HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		int id = Integer.parseInt(RequestUtil.getValue(request, "id"));
		List<Object> values = new ArrayList<Object>();
		values.add(sessionInfo.getKeyChar() + "%");
		values.add(id);
		List<Role> roles = this.getBaseDao().find("from Role r where r.organization.keyChar like ? and r.id = ?", values);
		if (roles.size() > 0) {
			Set<RoleAction> ras = roles.get(0).getRoleActions();
			String res = "";
			for (RoleAction ra : ras) {
				res = res + ra.getAction().getId() + ";";
			}
			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			modelMap.put("success", true);
			modelMap.put("msg", res);
			return modelMap;
		}
		return null;
	}

	@Transactional
	public Map<String, Object> save(HttpServletRequest request,
			HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		List<String> actions = sessionInfo.getActions();
		String actStr = "'0'";
		for (String action : actions) {
			actStr = actStr + ",'" + action + "'";
		}
		List<Action> acts = this.getBaseDao().find("from Action a where a.code in (" + actStr 
				+ ") and a.front = 0 and a.level >= ?", sessionInfo.getTypeValue().length());
		Map<Integer, Action> actMaps = new HashMap<Integer, Action>();
		for (Action act : acts) {
			actMaps.put(act.getId(), act);
		}
		Role role = (Role)this.getBaseDao().get(Role.class, Integer.valueOf(RequestUtil.getValue(request, "id")));
		if (!role.getOrganization().getKeyChar().equals(sessionInfo.getKeyChar()) 
				|| role.getOrganization().isDeleted()) return null;
		Set<RoleAction> ras = role.getRoleActions();
		Map<Integer, RoleAction> raMaps = new HashMap<Integer, RoleAction>();
		for (RoleAction ra : ras) {
			raMaps.put(ra.getAction().getId(), ra);
		}
		String idStr = RequestUtil.getValue(request, "str");
		List<Integer> flag = new ArrayList<Integer>();
		if (!"".equals(idStr)) {
			String[] ids = idStr.split(";");
			List<Integer> temp = new ArrayList<Integer>();
			int[] intIds = new int[ids.length];
			for (int i = 0; i < ids.length; i++) {
				intIds[i] = Integer.valueOf(ids[i]);
			}
			Arrays.sort(intIds);
			for (int intId : intIds) {
				if (actMaps.containsKey(intId)) {
					Action ac = actMaps.get(intId);
					if (ac.getCode().indexOf("?index") != -1) {
						temp.add(ac.getColumn().getId());
					} else {
						if (!temp.contains(ac.getColumn().getId())) continue;
					}
					if (!raMaps.containsKey(intId)) {
						RoleAction ra = new RoleAction();
						ra.setAction(ac);
						ra.setRole(role);
						this.getBaseDao().save(ra);
					} else {
						raMaps.remove(intId);
					}
				}
				flag.add(intId);
			}
		}
		role.setRoleActions(null);
		for (RoleAction ra : raMaps.values()) {
			this.getBaseDao().delete(ra);
		}
		String keyChar = role.getOrganization().getKeyChar() + role.getOrganization().getId() + ";%";
		List<RoleAction> rayas = this.getBaseDao().find("from RoleAction ra where ra.role.organization.keyChar like ?", keyChar);
		for (RoleAction ra : rayas) {
			if (!flag.contains(ra.getAction().getId())) {
				this.getBaseDao().delete(ra);
			}
		}
		Map<String,Object> modelMap = new HashMap<String,Object>(2);
		modelMap.put("success", true);
		modelMap.put("msg", "保存成功！");
		return modelMap;
	}
	

}
